<template>
  <div class="topo-main">
    <el-form
      label-width="80px"
      inline
    >
      <el-form-item :label="$t('template')">
        <el-select v-model="templateId" @change="templateChange">
          <el-option
            v-for="item in templateList"
            :key="item.templateId"
            :label="item.name"
            :value="item.templateId"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button
          type="primary"
          @click="insertTemplate"
        >{{ $t('insert')+$t('template') }}
        </el-button>
        <el-button
          type="primary"
          @click="updateTemplate"
        >{{ $t('update')+$t('template') }}
        </el-button>
        <el-button
          type="danger"
          @click="deleteTemplate"
        >{{ $t('delete')+$t('template') }}
        </el-button>
      </el-form-item>
      <el-form-item :label="$t('function')">
        <!--        <div style="line-height:40px;">-->
        <!--          {{ $t('choose') }}:{{ selectedComponents.length }}-->
        <!--        </div>-->
        <el-button
          type="primary"
          @click="fullScreen"
        >{{ $t('preview') }}
        </el-button>
        <el-button
          type="primary"
          @click="insertOrUpdateDeviceView"
        >{{ $t('save') }}
        </el-button>
        <el-button
          type="danger"
          @click="deleteDeviceView"
        >{{ $t('delete') }}
        </el-button>
      </el-form-item>
      <el-form-item :label="$t('zoom')">
        <el-slider
          v-model="selectedValue"
          :min="30"
          :max="200"
          style="width:200px;"
        />
      </el-form-item>
    </el-form>
    <vue-ruler-tool
      :parent="true"
      :is-scale-revise="true"
      style="width:100%;height: calc(100% - 55px);"
    >
      <div
        id="surface-edit-layer"
        tabindex="0"
        class="topo-layer"
        :class="{'topo-layer-view-selected': selectedIsLayer}"
        :style="layerStyle"
        @click="onLayerClick($event)"
        @mouseup="onLayerMouseup($event)"
        @mousemove="onLayerMousemove($event)"
        @mousedown="onLayerMousedown($event)"
        @keyup.delete="removeItem()"
        @dragover.prevent
        @drop="onDrop"
        @keydown.ctrl.67.stop="copyItem"
        @keydown.ctrl.86.stop="pasteItem"
        @keydown.ctrl.90.stop="undo"
        @keydown.ctrl.89.stop="redo"
      >
        <template v-for="(component,index) in configData.components">
          <div
            :key="component.identifier"
            tabindex="0"
            class="topo-layer-view"
            :class="{'topo-layer-view-selected': selectedComponentMap[component.identifier] == undefined? false:true }"
            :style="{
              'left': component.style.position.x + 'px',
              'top': component.style.position.y + 'px',
              'width': component.style.position.w + 'px',
              'height': component.style.position.h + 'px',
              'background-color': component.style.backColor,
              'z-index': component.style.zIndex,
              'border-radius': component.style.borderRadius,
              'border-width': component.style.borderWidth + 'px',
              'border-style': component.style.borderStyle,
              'border-color': component.style.borderColor,
              'transform': component.style.transform? `rotate(${component.style.transform}deg)`:'rotate(0deg)',
            }"
            @click.stop="clickComponent(index,component,$event)"
            @mousedown.stop="controlMousedown(component,$event,index)"
            @keyup.delete="removeItem()"
            @keydown.up.exact.prevent="moveItems('up')"
            @keydown.right.exact.prevent="moveItems('right')"
            @keydown.down.exact.prevent="moveItems('down')"
            @keydown.left.exact.prevent="moveItems('left')"
            @keydown.ctrl.67.stop="copyItem"
            @keydown.ctrl.86.stop="pasteItem"
            @keydown.ctrl.90.stop="undo"
            @keydown.ctrl.89.stop="redo"
          >
            <component
              :is="parseView(component)"
              v-show="component.style.visible"
              :ref="'comp' + index"
              :detail="component"
              :edit-mode="true"
              :selected="selectedComponentMap[component.identifier] ? true : false"
            />
            <div
              style="display: flex;justify-content: space-between;position: absolute;height: 30px;left: 0px;top: -30px;cursor: nwse-resize;"
            >
              <div
                v-if="component.dataBind"
                style="margin-right: 10px;background-color: white;border: 1px solid #0cf;line-height: 30px;"
              >{{
                component.dataBind.name }}
              </div>
              <div v-if="component.dataBind && component.dataBind.showTypeList" :label="$t('type')">
                <el-select
                  v-model="component.dataBind.showType"
                  style="width: 100px"
                >
                  <el-option
                    v-for="(showType,showTypeIndex) in component.dataBind.showTypeList"
                    :key="showTypeIndex"
                    :label="showType.label"
                    :value="showType.value"
                  />
                </el-select>
              </div>
            </div>
            <div
              v-show="selectedComponentMap[component.identifier]"
              class="resize-left-top"
              @mousedown.stop="resizeMousedown(component,$event,index,'resize-lt')"
            />
            <div
              v-show="selectedComponentMap[component.identifier]"
              class="resize-left-center"
              @mousedown.stop="resizeMousedown(component,$event,index,'resize-lc')"
            />
            <div
              v-show="selectedComponentMap[component.identifier]"
              class="resize-left-bottom"
              @mousedown.stop="resizeMousedown(component,$event,index,'resize-lb')"
            />
            <div
              v-show="selectedComponentMap[component.identifier]"
              class="resize-right-top"
              @mousedown.stop="resizeMousedown(component,$event,index,'resize-rt')"
            />
            <div
              v-show="selectedComponentMap[component.identifier]"
              class="resize-right-center"
              @mousedown.stop="resizeMousedown(component,$event,index,'resize-rc')"
            />
            <div
              v-show="selectedComponentMap[component.identifier]"
              class="resize-right-bottom"
              @mousedown.stop="resizeMousedown(component,$event,index,'resize-rb')"
            />
            <div
              v-show="selectedComponentMap[component.identifier]"
              class="resize-center-top"
              @mousedown.stop="resizeMousedown(component,$event,index,'resize-ct')"
            />
            <div
              v-show="selectedComponentMap[component.identifier]"
              class="resize-center-bottom"
              @mousedown.stop="resizeMousedown(component,$event,index,'resize-cb')"
            />
          </div>
        </template>
        <div
          class="topo-frame-selection"
          :style="{width: frameSelectionDiv.width + 'px',height: frameSelectionDiv.height + 'px',top: frameSelectionDiv.top + 'px',left: frameSelectionDiv.left + 'px'}"
        />
      </div>
    </vue-ruler-tool>
  </div>
</template>

<script>
import VueRulerTool from './VueRulerTool'
import TopoBase from './TopoBase'
import topoUtil from './util/topo-util'
import {
  deepCopy
} from '@/topo/assets/libs/utils'
import {
  checkByRectCollisionDetection
} from '@/topo/assets/libs/topo'
import {
  mapActions,
  mapGetters,
  mapState,
  mapMutations
} from 'vuex'
import {
  insertOrUpdateDeviceView,
  deleteDeviceView
} from '@/api/iot/iotDeviceViewApi'
import {
  getDevice
} from '@/api/iot/iotDeviceApi'
import {
  failureNotice,
  successNotice,
  cancelNotice
} from '@/util/common'
import {
  listDeviceViewTemplate,
  updateDeviceViewTemplate,
  deleteDeviceViewTemplate,
  insertDeviceViewTemplate
} from '@/api/iot/iotDeviceViewTemplateApi'

export default {
  name: 'TopoMain',
  components: {
    VueRulerTool
  },
  extends: TopoBase,
  props: [],
  computed: {
    ...mapState({
      selectedComponents: state => state.topoEditor.selectedComponents,
      selectedComponentMap: state => state.topoEditor.selectedComponentMap,
      configData: state => state.topoEditor.topoData,
      selectedIsLayer: state => state.topoEditor.selectedIsLayer,
      copySrcItems: state => state.topoEditor.copySrcItems,
      copyCount: state => state.topoEditor.copyCount
    }),
    layerStyle: function() {
      const scale = this.selectedValue / 100
      const styles = [`transform:scale(${scale})`]
      if (this.configData.layer.backColor) {
        styles.push(`background-color: ${this.configData.layer.backColor}`)
      }
      if (this.configData.layer.width > 0) {
        styles.push(`width: ${this.configData.layer.width}px`)
      }
      if (this.configData.layer.height > 0) {
        styles.push(`height: ${this.configData.layer.height}px`)
      }
      const style = styles.join(';')
      return style
    }
  },
  data() {
    return {
      moveItem: {
        startX: 0,
        startY: 0
      }, // 移动组件 相关变量
      resizeItem: {
        startPx: 0,
        startPy: 0,
        x: 0,
        y: 0,
        w: 0,
        h: 0
      }, // resize组件 相关变量
      frameSelectionDiv: {
        width: 0,
        height: 0,
        top: 10,
        left: 10,
        startX: 0,
        startY: 0,
        startPageX: 0,
        startPageY: 0
      },
      flag: '', // 当前操作标志位
      curControl: null,
      curIndex: -1,
      selectedValue: 100,
      viewId: null,
      templateId: null,
      templateList: [],
      device: {}
    }
  },
  created() {
    const param = this.$route.query
    this.deviceCore = param.deviceCore
    this.getDevice()
    this.listDeviceViewTemplate()
  },
  methods: {
    getDevice() {
      getDevice({
        deviceCore: this.deviceCore
      }).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.device = data
        }
      })
    },
    templateChange() {
      this.configData.components.forEach((index, component) => {
        this.removeItem(index, component)
      })
      for (let i = 0, j = this.templateList.length; i < j; i++) {
        const template = this.templateList[i]
        if (template.templateId === this.templateId) {
          const jsonConfig = JSON.parse(template.jsonConfig)
          if (jsonConfig.components) {
            jsonConfig.components.forEach((component) => {
              component.dataBind.deviceCore = this.deviceCore
            })
          }
          this.setTopoData(jsonConfig)
        }
      }
    },
    listDeviceViewTemplate() {
      listDeviceViewTemplate({
        userId: this.userId,
        productId: this.device.productId,
        seriesId: this.device.seriesId
      }).then(res => {
        const { code, data } = res
        if (code === '200') {
          this.templateList = data
          if (data.length > 0) {
            this.templateId = data[0].templateId
            this.templateChange()
          }
        } else {
          this.templateList = []
        }
      })
    },
    insertTemplate() {
      const that = this
      this.$prompt(this.$t('name'), this.$t('prompt'), {
        confirmButtonText: this.$t('confirm'),
        cancelButtonText: this.$t('cancel')
      }).then(({ value }) => {
        if (value === '') {
          failureNotice(that)
          return
        }
        this.loadDefaultTopoData()
        const configData = JSON.parse(JSON.stringify(this.configData))
        configData.components.forEach(component => {
          component.dataBind.editModel = false
        })
        const jsonConfig = JSON.stringify(configData)

        insertDeviceViewTemplate({
          jsonConfig: jsonConfig,
          name: value,
          productId: this.device.productId,
          seriesId: this.device.seriesId
        }).then(res => {
          const { code } = res
          if (code === '200') {
            successNotice(that)
          }
          that.listDeviceViewTemplate()
        })
      }).catch(() => {
        cancelNotice(that)
      })
    },
    deleteTemplate() {
      const that = this
      this.$confirm(this.$t('delete'), this.$t('prompt'), {
        confirmButtonText: this.$t('confirm'),
        cancelButtonText: this.$t('cancel'),
        type: 'warning'
      })
        .then(function() {
          deleteDeviceViewTemplate({
            templateId: that.templateId
          }).then(res => {
            const { code } = res
            if (code === '200') {
              successNotice(that)
            }
            that.listDeviceViewTemplate()
          })
        })
        .catch(function() {
          cancelNotice(that)
        })
    },
    updateTemplate() {
      const configData = JSON.parse(JSON.stringify(this.configData))
      configData.components.forEach(component => {
        component.dataBind.editModel = false
      })
      const jsonConfig = JSON.stringify(configData)

      updateDeviceViewTemplate({
        jsonConfig: jsonConfig,
        templateId: this.templateId
      }).then(res => {
        const { code } = res
        if (code === '200') {
          successNotice(this)
        }
        this.listDeviceViewTemplate()
      })
    },
    ...mapMutations('topoEditor', [
      'setSelectedComponent',
      'addSelectedComponent',
      'removeSelectedComponent',
      'clearSelectedComponent',
      'setLayerSelected',
      'setCopySrcItems',
      'increaseCopyCount',
      'execute',
      'undo',
      'redo'
    ]),
    ...mapActions('topoEditor', [
      'loadDefaultTopoData',
      'setTopoData'
    ]),
    controlMousedown(component, event, index) {
      if (event.ctrlKey) {
        return
      }
      this.flag = 'move'
      this.curControl = component
      this.clickItem(component, index)
      this.moveItem.startX = event.pageX
      this.moveItem.startY = event.pageY
      // 记录初始信息--move
      for (const key in this.selectedComponentMap) {
        const component = this.selectedComponentMap[key]
        component.style.temp = {}
        component.style.temp.position = {}
        component.style.temp.position.x = component.style.position.x
        component.style.temp.position.y = component.style.position.y
      }
    },
    resizeMousedown(component, $event, index, flag) { // resize-鼠标按下事件
      this.flag = flag
      this.curControl = component
      this.curIndex = index
      this.clickItem(component, index)
      this.resizeItem.startPx = event.pageX
      this.resizeItem.startPy = event.pageY
      // 记录初始信息-resize
      this.resizeItem.x = this.curControl.style.position.x
      this.resizeItem.y = this.curControl.style.position.y
      this.resizeItem.w = this.curControl.style.position.w
      this.resizeItem.h = this.curControl.style.position.h
    },
    onLayerMousemove(event) {
      if (event.which !== 1) {
        this.flag = ''
        return
      }
      if (this.flag === '') {
        return
      }
      if (this.flag.startsWith('resize')) {
        let dx = event.pageX - this.resizeItem.startPx
        let dy = event.pageY - this.resizeItem.startPy
        switch (this.flag) {
          case 'resize-lt':
            this.curControl.style.position.x = this.resizeItem.x + dx
            this.curControl.style.position.y = this.resizeItem.y + dy
            dx = -dx
            dy = -dy
            break
          case 'resize-lc':
            this.curControl.style.position.x = this.resizeItem.x + dx
            dy = 0
            dx = -dx
            break
          case 'resize-lb':
            this.curControl.style.position.x = this.resizeItem.x + dx
            dx = -dx
            break
          case 'resize-rt':
            this.curControl.style.position.y = this.resizeItem.y + dy
            dy = -dy
            break
          case 'resize-rc':
            dy = 0
            break
          case 'resize-rb':
            break
          case 'resize-ct':
            this.curControl.style.position.y = this.resizeItem.y + dy
            dx = 0
            dy = -dy
            break
          case 'resize-cb':
            dx = 0
            break
        }
        if ((this.resizeItem.w + dx) > 20) {
          this.curControl.style.position.w = this.resizeItem.w + dx
        }
        if ((this.resizeItem.h + dy) > 20) {
          this.curControl.style.position.h = this.resizeItem.h + dy
        }
        // canvas组件需要重新渲染
        // DOM 还没有更新
        this.$nextTick(function() {
          // DOM 更新了
          const a = this.$refs['comp' + this.curIndex][0]
          a.onResize()
        })
      } else if (this.flag === 'move') {
        // 移动组件
        const dx = event.pageX - this.moveItem.startX
        const dy = event.pageY - this.moveItem.startY
        for (const key in this.selectedComponentMap) {
          const component = this.selectedComponentMap[key]
          component.style.position.x = component.style.temp.position.x + dx
          component.style.position.y = component.style.temp.position.y + dy
        }
      } else if (this.flag === 'frame_selection') {
        this.onFrameSelection(event)
      }
    },
    onLayerMouseup(event) {
      if (this.flag.startsWith('resize')) {
        const a = this.$refs['comp' + this.curIndex][0]
        a.onResize()
      } else if (this.flag === 'frame_selection') {
        // 由于和onLayerClick冲突，这里模拟下点击空白区域
        this.onFrameSelection(event)
        this.frameSelectionDiv.width = 0
        this.frameSelectionDiv.height = 0
        this.frameSelectionDiv.top = 0
        this.frameSelectionDiv.left = 0
      } else if (this.flag === 'move') {
        // 鼠标move只是方便用户预览，真正执行应该用命令，所以要先恢复
        const dx = event.pageX - this.moveItem.startX
        const dy = event.pageY - this.moveItem.startY
        for (const key in this.selectedComponentMap) {
          const component = this.selectedComponentMap[key]
          component.style.position.x = component.style.position.x - dx
          component.style.position.y = component.style.position.y - dy
        }
        this.execute({
          op: 'move',
          dx: dx,
          dy: dy,
          items: this.selectedComponentMap
        })
      }
      this.flag = ''
    },
    onLayerMousedown($event) {
      this.flag = 'frame_selection'
      this.frameSelectionDiv.startX = event.offsetX
      this.frameSelectionDiv.startY = event.offsetY
      this.frameSelectionDiv.startPageX = event.pageX
      this.frameSelectionDiv.startPageY = event.pageY
    },
    onLayerClick() {
      // this.clearSelectedComponent();
      // this.setLayerSelected(true);
    },
    onFrameSelection(event) {
      const dx = event.pageX - this.frameSelectionDiv.startPageX
      const dy = event.pageY - this.frameSelectionDiv.startPageY
      this.frameSelectionDiv.width = Math.abs(dx)
      this.frameSelectionDiv.height = Math.abs(dy)
      if (dx > 0 && dy > 0) {
        this.frameSelectionDiv.top = this.frameSelectionDiv.startY
        this.frameSelectionDiv.left = this.frameSelectionDiv.startX
      } else if (dx > 0 && dy < 0) {
        this.frameSelectionDiv.top = this.frameSelectionDiv.startY + dy
        this.frameSelectionDiv.left = this.frameSelectionDiv.startX
      } else if (dx < 0 && dy > 0) {
        this.frameSelectionDiv.top = this.frameSelectionDiv.startY
        this.frameSelectionDiv.left = this.frameSelectionDiv.startX + dx
      } else if (dx < 0 && dy < 0) {
        this.frameSelectionDiv.top = this.frameSelectionDiv.startY + dy
        this.frameSelectionDiv.left = this.frameSelectionDiv.startX + dx
      }
      // 判断各个组件是否在方框内
      const rect = {
        x: this.frameSelectionDiv.left,
        y: this.frameSelectionDiv.top,
        width: this.frameSelectionDiv.width,
        height: this.frameSelectionDiv.height
      }
      const components = this.configData.components
      components.forEach(component => {
        const itemRect = {
          x: component.style.position.x,
          y: component.style.position.y,
          width: component.style.position.w,
          height: component.style.position.h
        }
        if (checkByRectCollisionDetection(rect, itemRect)) {
          this.addSelectedComponent(component)
        } else {
          this.removeSelectedComponent(component)
        }
      })
      if (this.selectedComponents.length > 0) {
        this.setLayerSelected(false)
      } else {
        this.setLayerSelected(true)
      }
    },
    onDrop(event) {
      event.preventDefault()
      const infoJson = event.dataTransfer.getData('my-info')
      const component = JSON.parse(infoJson)
      if (this.checkAddComponent(component) === false) {
        return
      }
      // 判断当前着陆点是不是layer
      if (event.target.id === 'surface-edit-layer') {
        component.style.position.x = event.offsetX
        component.style.position.y = event.offsetY
      } else {
        // 解决着陆灯不是layer的情形
        const layer = event.currentTarget
        const position = layer.getBoundingClientRect()
        const x = event.clientX - position.left
        const y = event.clientY - position.top
        component.style.position.x = x
        component.style.position.y = y
      }
      // 处理默认值
      this.execute({
        op: 'add',
        component: component
      })
      // 默认选中，并点击
      this.clickItem(component, this.configData.components.length - 1)
    },
    moveItems(direction) {
      let dx = 0
      let dy = 0
      if (direction === 'up') {
        dy = -5
      } else if (direction === 'right') {
        dx = 5
      } else if (direction === 'down') {
        dy = 5
      } else if (direction === 'left') {
        dx = -5
      }
      this.execute({
        op: 'move',
        dx: dx,
        dy: dy,
        items: this.selectedComponentMap
      })
    },
    checkAddComponent(info) {
      if (info == null) {
        this.$q.notify({
          type: 'negative',
          position: 'bottom-right',
          message: 'This component not surpport.'
        })
        return false
      }
      return true
    },
    parseView(component) {
      return topoUtil.parseViewName(component)
    },
    clickItem(component, index) {
      this.setLayerSelected(false)
      if (this.selectedComponentMap[component.identifier] === undefined) {
        this.setSelectedComponent(component)
      } else {
        // 如果已经选中，则不做任何处理
      }
    },
    clickComponent(index, component, event) { // 点击组件
      if (event.ctrlKey === true) { // 点击了ctrl
        this.setLayerSelected(false)
        if (this.selectedComponentMap[component.identifier] === undefined) {
          this.addSelectedComponent(component)
        } else {
          this.removeSelectedComponent(component)
        }
      } else {
        // 这里不再处理点击事件，改为鼠标左键
        // this.clickItem(component,index);
      }
    },
    copyItem() { // 设定复制源
      const items = []
      for (const key in this.selectedComponentMap) {
        const item = deepCopy(this.selectedComponentMap[key])
        items.push(item)
      }
      this.setCopySrcItems(items)
    },
    pasteItem() {
      if (this.copySrcItems && this.copySrcItems.length > 0) {
        this.execute({
          op: 'copy-add',
          items: this.copySrcItems
        })
      }
    },
    removeItem(index, component) { // 移除组件
      this.execute({
        op: 'del',
        index: index
      })
      this.setLayerSelected(true)
    },
    fullScreen() {
      localStorage.setItem('topoData', JSON.stringify(this.configData))
      this.$router.push({
        path: '/topo/fullscreen',
        name: 'TopoFullscreen',
        query: { deviceCore: this.deviceCore }
      })
    },
    deleteDeviceView() {
      deleteDeviceView({
        deviceCore: this.deviceCore,
        templateId: this.templateId
      }).then(res => {
        const { code } = res
        if (code === '200') {
          successNotice(this)
        }
      })
    },
    insertOrUpdateDeviceView() {
      const configData = JSON.parse(JSON.stringify(this.configData))
      configData.components.forEach(component => {
        component.dataBind.editModel = false
      })
      insertOrUpdateDeviceView({
        deviceCore: this.deviceCore,
        templateId: this.templateId
      }).then(res => {
        const { code } = res
        if (code === '200') {
          successNotice(this)
        }
      })
    }
  }
}
</script>

<style lang="scss">
  .topo-main {
    position: relative;
    overflow-x: hidden;
    overflow-y: hidden;

    .topo-layer {
      width: 100%;
      height: 100%;
      position: absolute;
      transform-origin: left top;
      overflow: auto;
      // background-color: white;
      // background-clip: padding-box;
      // background-origin: padding-box;
      // background-repeat: no-repeat;
      // background-size: 100% 100%;

      background-image: linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc),
      linear-gradient(45deg, #ccc 25%, transparent 25%, transparent 75%, #ccc 75%, #ccc);
      background-size: 20px 20px;
      background-position: 0 0, 10px 10px;

      .topo-frame-selection {
        background-color: #8787e7;
        opacity: 0.3;
        border: #0000ff solid 1px;
        position: absolute;
        z-index: 999;
      }

      .topo-layer-view {
        position: absolute;
        height: 100px;
        width: 100px;
        background-color: #999;
        cursor: move;
        border: #ccc solid 1px;

        .resize-left-top {
          position: absolute;
          height: 10px;
          width: 10px;
          background-color: white;
          border: 1px solid #0cf;
          left: -5px;
          top: -5px;
          cursor: nwse-resize;
        }

        .resize-left-center {
          position: absolute;
          height: 10px;
          width: 10px;
          background-color: white;
          border: 1px solid #0cf;
          left: -5px;
          top: 50%;
          margin-top: -5px;
          cursor: ew-resize;
        }

        .resize-left-bottom {
          position: absolute;
          height: 10px;
          width: 10px;
          background-color: white;
          border: 1px solid #0cf;
          left: -5px;
          bottom: -5px;
          cursor: nesw-resize;
        }

        .resize-right-top {
          position: absolute;
          height: 10px;
          width: 10px;
          background-color: white;
          border: 1px solid #0cf;
          right: -5px;
          top: -5px;
          cursor: nesw-resize;
        }

        .resize-right-center {
          position: absolute;
          height: 10px;
          width: 10px;
          background-color: white;
          border: 1px solid #0cf;
          right: -5px;
          top: 50%;
          margin-top: -5px;
          cursor: ew-resize;
        }

        .resize-right-bottom {
          position: absolute;
          height: 10px;
          width: 10px;
          background-color: white;
          border: 1px solid #0cf;
          right: -5px;
          bottom: -5px;
          cursor: nwse-resize;
        }

        .resize-center-top {
          position: absolute;
          height: 10px;
          width: 10px;
          background-color: white;
          border: 1px solid #0cf;
          top: -5px;
          left: 50%;
          margin-left: -5px;
          cursor: ns-resize;
        }

        .resize-center-bottom {
          position: absolute;
          height: 10px;
          width: 10px;
          background-color: white;
          border: 1px solid #0cf;
          bottom: -5px;
          left: 50%;
          margin-left: -5px;
          cursor: ns-resize;
        }
      }

      .topo-layer-view-selected {
        outline: 1px solid #0cf;
      }
    }
  }
</style>
